local sp = Node.Sprite():addTo(Layer.Stage)

local strokes = {}

local curStroke
local function insertPoint(x, y)
    local p = {x, y}
    table.insert(curStroke, p)
end
sp:on(NodeEvent.Pressed, function (x, y)
    curStroke = {}
    insertPoint(x, y)
end)

sp:on(NodeEvent.Moved, function (x, y)
    insertPoint(x, y)
end)

sp:on(NodeEvent.Released, function (x, y)
    insertPoint(x, y)
    table.insert(strokes, curStroke)
    curStroke = nil
end)


local testSp = Node.Sprite():addTo(Layer.Stage)
testSp:addComponent(Stretch)
-- testSp.material = Material.new("strokes")
-- testSp.material:set("imageSize", {100, 100, 0, 0})
-- testSp.material:set("thickness", 5)
-- testSp.material:set("smoothess", 3)
-- testSp.material:set("p1", {10, 10})
-- testSp.material:set("p2", {90, 90})

-- local testLabel = Node.Label("龙"):addTo(Layer.Stage)
-- testLabel.fontSize = 100

local graphic = Node.Graphic():addTo(Layer.Stage)
graphic:wh(512, 512)
graphic:beginPaint(1, 0,1, 1)
love.graphics.setColor(1, 0, 0, 1)
graphic:rectangle(0, 0, 601, 601)
love.graphics.setColor(0, 0, 0, 1)
graphic:label("龙", 400, "core/resources/fonts/AaYueRanTi-2.ttf")
graphic:endPaint()
love.graphics.setColor(1, 1, 1, 1)


local imageData = graphic._canvas:newImageData()
local pixels = {}
local map = Map2d.new()
imageData:mapPixel(function (x, y, r, g, b, a)
    if r ~= 1 then
        map:set(x, y, true)
        table.insert(pixels, {x, y})
        -- return 1, 1, 1, 1
    else
        map:set(x, y, false)
    end
    return r, g, b, a
end)

local borderPixels = Map2d.new()
local borderPixelList = {}
for i = 1, map.cols do
    for j = 1, map.rows do
        if map:get(i, j) then
            for t =-1, 1 do
                for t2 = -1, 1 do
                    local x, y = i + t, j + t2
                    if x > 0 and y > 0 and x <= map.cols and y <= map.rows then
                        local v = map:get(x, y)
                        if not v then
                            borderPixels:set(i, j, true)
                            table.insert(borderPixelList, {i, j})
                            -- imageData:setPixel(i, j, 1, 1, 1, 1)
                        end
                    end
                end
            end
        end
    end
end

local strokes = {}
local function findStroke(x, y)
    for _, s in ipairs(strokes) do
        if s:get(x, y) then
            return
        end
    end
    Console.log("createStroke from", x, y)
    local toVisit = {{x, y}}
    local visited = Map2d.new()

    local function visit(x, y)
        if visited:get(x, y) then
            return
        end
        if not borderPixels:get(x, y) then
            return
        end
        visited:set(x, y, true)
        for i = -1, 1 do
            for j = -1, 1 do
                table.insert(toVisit, {x + i, y + j})
            end
        end
    end
    while #toVisit > 0 do
        local p = table.remove(toVisit, 1)
        visit(p[1], p[2])
    end

    table.insert(strokes, visited)
end
for i, v in ipairs(borderPixelList) do
    findStroke(v[1], v[2])
end

local colors = {
    Color.white,
    Color.blue,
    Color.green,
    Color.pink
}

local function paintStroke(i)
    local color = colors[i]
    if i > #colors then
        return
    end
    local r, g, b, a = color:rgba()
    local s = strokes[i]
    s:map(function (x, y, v)
        if v then
            imageData:setPixel(x, y, r, g, b, a)
        end
    end)
end
for i, s in ipairs(strokes) do
    paintStroke(i)
end

graphic.material:setTexture(love.graphics.newImage(imageData))
graphic.renderInfoDirty = true


local ui = Node.Layout():addTo(Layer.UI)
ui:addComponent(Sprite)
ui.color = Color.gray
ui:addComponent(Align)
ui.alignPercentX = 1
ui.alignPercentY = 0
ui:axy(1, 0)
ui.layoutSizeMode = LayoutSizeMode.Stretch
local btnMakePoints = Node.Button("生成关键点"):addTo(ui)
btnMakePoints:onClick(function ()
    for _, s in ipairs(strokes) do
        local stroke = Stroke.new(s)
        stroke:generatePoints()
        local start = stroke.start
        local point = start
        local sp = Node.Sprite():wh(5, 5):addTo(graphic)
        sp:addComponent(Align)
        sp.alignPercentX = 0
        sp.alignPercentY = 0
        sp.alignOffsetX = start.x
        sp.alignOffsetY = start.y

        while(point.nextPoint ~= start) do
            point = point.nextPoint
            local sp = Node.Sprite():wh(5, 5):addTo(graphic)
            sp:addComponent(Align)
            sp.alignPercentX = 0
            sp.alignPercentY = 0
            sp.alignOffsetX = point.x
            sp.alignOffsetY = point.y
            sp:addComponent(Drag)
        end
    end
end)

local switch = Node.Switch("切割"):addTo(ui)
switch:onSwitchOn(function ()
    
end)
switch:onSwitchOff(function ()
    
end)